//author: Sun chengjie 
//date: 2004-09-29 

//textfile.h: interface for the TextFile class. 
////////////////////////////////////////////////////////////////////// 

#ifndef TextFile_h 
#define TextFile_h 


#include <fstream> 
#include <string> 
using namespace std; 

class CTextFileBase 
{ 
public: 
	enum TEXTENCODING { ASCII, UNI16_BE, UNI16_LE, UTF_8 }; 

	CTextFileBase(); 
	~CTextFileBase(); 

	int IsOpen(); //Is the file open? 
	virtual void Close();//Close the file 
	TEXTENCODING GetEncoding() const; //Return the encoding of the file (ASCII, UNI16_BE, UNI16_LE or UTF_8); 

protected: 

	void CharToWstring(const char* from, wstring &to) const; //Convert char* to wstring 
	void WcharToString(const wchar_t* from, string &to) const; //Convert wchar_t* to string 

	TEXTENCODING m_encoding; //The enocoding of the file	 
#define BUFFSIZE 1024  //Buffersize 
	fstream m_file; 

	//These controls the buffer for reading/writing 
	bool m_endoffile; //True if end of file 
	char m_buf[BUFFSIZE]; //Readingbuffer 
	int m_buffpos;  //Bufferposition 
	int m_buffsize; //Size of buffer 

}; 


#ifndef _UNICODE 
typedef char FILENAMECHAR; 
#else 
typedef wchar_t FILENAMECHAR; 
#endif 

class CTextFileWrite : public CTextFileBase 
{ 

public: 
	CTextFileWrite(const FILENAMECHAR* filename, TEXTENCODING type=ASCII); 
	~CTextFileWrite(); 

	//Write routines 
	void Write(const char* text); 
	void Write(const wchar_t* text); 

	CTextFileWrite& operator < (const char wc); 
	CTextFileWrite& operator < (const char* text); 

	CTextFileWrite& operator < (const wchar_t wc); 
	CTextFileWrite& operator < (const wchar_t* text); 

	//Write new line (two characters, 13 and 10) 
	void WriteEndl(); 

	//Close the file 
	virtual void Close(); 

private: 
	//Write and empty buffer 
	void Flush(); 

	//Write a single one wchar_t, convert first 
	void WriteWchar(const wchar_t ch); 

	//Write one byte 
	void WriteByte(const unsigned char byte); 

	//Write a c-string in ASCII-format 
	void WriteAsciiString(const char* s); 

	//Write byte order mark 
	void WriteBOM(); 
}; 


class CTextFileRead : public CTextFileBase 
{ 

public: 
	CTextFileRead(const FILENAMECHAR* filename); 

	//Reading functions. Returns false if eof. 
	bool ReadLine(string& line); 
	bool ReadLine(wstring& line); 

	bool Read(string& all, const string newline="\r\n"); 
	bool Read(wstring& all, const wstring newline=L"\r\n"); 

	bool Eof() const;//End of file? 

private: 

	int GuessCharacterCount(); //Guess the number of characters in the file 

	bool ReadWcharLine(wstring& line);//Read line to wstring 
	bool ReadCharLine(string& line);//Read line to string 
	void ResetFilePointer();//Reset the filepointer to start 
	void ReadWchar(wchar_t& ch);//Read one wchar_t 
	void ReadByte(unsigned char& ch);//Read one byte 
	void ReadBOM();//Detect encoding 

	//Use extra buffer. Sometimes we read one character to much, save it. 
	bool m_useExtraBuffer; 
	//Extra buffer. It's ok to share the memory 
	union 
	{ 
		char m_extraBuffer_char; 
		wchar_t m_extraBuffer_wchar; 
	}; 

}; 


#endif